package com.cndw.kungfu.domain;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.cndw.asyncsync.SyncObject;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.ext.JsonProcesser;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.StringProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.battle.Fighter;
import com.cndw.kungfu.model.battle.FighterPet;
import com.cndw.kungfu.model.pet.domain.PetSoul;
import com.cndw.kungfu.model.pet.domain.Soul;
import com.cndw.kungfu.model.player.FormulaScore;
import com.cndw.kungfu.vo.PetVO;
import com.cndw.kungfu.vo.battlevo.BattlePetVO;
import com.cndw.rpg.framework.ResponseMessage;

/**
 * 玩家宠物实例
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2012-4-7 下午2:13:55
 */
public class Pet extends SyncObject {
	/**
	 * 宠物编号
	 */
	private long id;
	/**
	 * 角色id
	 */
	private long playerId;
	/**
	 * 名称
	 */
	private String name;
	/**
	 * 模型
	 */
	private int modeId;

	private int level;
	/**
	 * 成长值
	 */
	private int growth;
	/**
	 * 星级,进化次数
	 */
	private int star;
	/**
	 * 悟性,修炼
	 */
	private int perception;
	/**
	 * 灵性修炼
	 */
	private int spirit;
	/**
	 * 经验
	 */
	private long exp;
	// 基础属性
	private int hp;
	private int mp;
	private int maxHp;
	private int maxMp;
	private int attack;
	private int defense;
	private int hit;
	private int dodge;
	private int crit;
	private int tough;
	private int speed;
	/**
	 * 技能
	 */
	private String skill;

	private int[] skillIds = {};
	/**
	 * 技能格子
	 */
	private int skillGird;
	/**
	 * 兽魂命格
	 */
	private String hunts;
	/**
	 * 兽魂命格队形
	 */
	private Map<Integer, Soul> huntsMap = new HashMap<Integer, Soul>();
	/**
	 * 战力评分
	 */
	private int score;
	/**
	 * 创建时间
	 */
	private int createTime;

	private Fighter linkedFighter;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public long getPlayerId() {
		return playerId;
	}

	public void setPlayerId(long playerId) {
		this.playerId = playerId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getModeId() {
		return modeId;
	}

	public void setModeId(int modeId) {
		this.modeId = modeId;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public int getGrowth() {
		return growth;
	}

	public void setGrowth(int growth) {
		this.growth = growth;
	}

	public int getStar() {
		return star;
	}

	public void setStar(int star) {
		this.star = star;
	}

	public int getPerception() {
		return perception;
	}

	public void setPerception(int perception) {
		this.perception = perception;
	}

	public long getExp() {
		return exp;
	}

	public void setExp(long exp) {
		this.exp = exp;
	}

	public int getHp() {
		return hp;
	}

	public void setHp(int hp) {
		this.hp = hp;
	}

	public int getMp() {
		return mp;
	}

	public void setMp(int mp) {
		this.mp = mp;
	}

	public int getMaxHp() {
		return maxHp;
	}

	public void setMaxHp(int maxHp) {
		this.maxHp = maxHp;
	}

	public int getMaxMp() {
		return maxMp;
	}

	public void setMaxMp(int maxMp) {
		this.maxMp = maxMp;
	}

	public int getAttack() {
		return attack;
	}

	public void setAttack(int attack) {
		this.attack = attack;
	}

	public int getDefense() {
		return defense;
	}

	public void setDefense(int defense) {
		this.defense = defense;
	}

	public int getHit() {
		return hit;
	}

	public void setHit(int hit) {
		this.hit = hit;
	}

	public int getDodge() {
		return dodge;
	}

	public void setDodge(int dodge) {
		this.dodge = dodge;
	}

	public int getCrit() {
		return crit;
	}

	public void setCrit(int crit) {
		this.crit = crit;
	}

	public int getTough() {
		return tough;
	}

	public void setTough(int tough) {
		this.tough = tough;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public int getSkillGird() {
		return skillGird;
	}

	public void setSkillGird(int skillGird) {
		this.skillGird = skillGird;
	}

	public String getSkill() {
		try {
			skill = StringProcesser.toString(skillIds);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return skill;
	}

	public void setSkill(String skill) {
		if (skill != null && skill.length() > 0) {
			try {
				skillIds = StringProcesser.toIntArray(skill);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		this.skill = skill;
	}

	public String getHunts() {
		if (huntsMap != null && !huntsMap.isEmpty()) {
			try {
				hunts = JsonProcesser.objectJsonEncode(huntsMap.values());
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (huntsMap.isEmpty()) {// 如果全部清理了也得把它还原
			hunts = null;
		}
		return hunts;
	}

	public void setHunts(String hunts) {
		this.hunts = hunts;
		if (hunts != null && hunts.length() > 0) {
			try {
				List<Soul> souls = JsonProcesser.objectJsonArrayDecode(hunts, Soul.class);
				int i = 0;
				for (Soul e : souls) {
					huntsMap.put(++i, e);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public Map<Integer, Soul> getHuntsMap() {
		return huntsMap;
	}

	public void setHuntsMap(Map<Integer, Soul> huntsMap) {
		this.huntsMap = huntsMap;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public int getCreateTime() {
		return createTime;
	}

	public void setCreateTime(int createTime) {
		this.createTime = createTime;
	}

	public int[] getSkillIds() {
		return skillIds;
	}

	public void setSkillIds(int[] skillIds) {
		this.skillIds = skillIds;
	}

	public synchronized void clacPropertys() {
		PetMode petMode = Context.getPetServer().getPetMode(modeId);
		int coefficient = growth * 10 * star * level / 2;
		try {
			int add = 0;
			if (perception > 0) {
				add += ConstantsModel.petPreAdd[perception - 1];
			}
			if (spirit > 0) {
				add += ConstantsModel.petSpiritAdd[spirit - 1];
			}
			if (add > 0) {
				coefficient = coefficient * (1000 + add) / 1000;
			}
		} catch (Exception e) {
		}
		int growthBase = 1000;
		if (coefficient * petMode.getHp() > 0) {
			maxHp = coefficient * petMode.getHp() / growthBase;
			maxMp = coefficient * petMode.getMp() / growthBase;
		} else {
			maxHp = (int)(coefficient * 1L * petMode.getHp() / growthBase);
			maxMp = (int)(coefficient * 1L * petMode.getMp() / growthBase);
		}
		attack = coefficient * petMode.getAttack() / growthBase;
		defense = coefficient * petMode.getDefense() / growthBase;
		hit = coefficient * petMode.getHit() / growthBase;
		dodge = coefficient * petMode.getDodge() / growthBase;
		crit = coefficient * petMode.getCrit() / growthBase;
		tough = coefficient * petMode.getTough() / growthBase;
		speed = coefficient * petMode.getSpeed() / growthBase;

		if (skillIds != null && skillIds.length > 0) {
			for (int eId : skillIds) {
				SkillMode skillMode = Context.getSkillServer().getSkillMode(eId);
				if (skillMode != null && skillMode.getPassiveType() > 0 && skillMode.getPassiveValue() > 0) {
					switch (skillMode.getPassiveType()) {
					case Constants.skillPassiveTypeHit:
						hit += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeDodge:
						dodge += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeCrit:
						crit += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeTough:
						tough += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeAttack:
						attack += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeDefense:
						defense += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeHp:
						maxHp += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeMp:
						maxMp += skillMode.getPassiveValue();
						break;
					case Constants.skillPassiveTypeSpeed:
						speed += skillMode.getPassiveValue();
						break;
					}
				}
			}
		}
		if (huntsMap != null && !huntsMap.isEmpty()) {
			try {
				for (Soul e : huntsMap.values()) {
					PetSoul petSoul = Context.getPetServer().getSoul(e.getId());
					if (petSoul != null && petSoul.getAddV() != null) {
						int[] skillAdd = petSoul.getAddV();
						hit += skillAdd[0];
						dodge += skillAdd[1];
						crit += skillAdd[2];
						tough += skillAdd[3];
						attack += skillAdd[4];
						defense += skillAdd[5];
						maxHp += skillAdd[6];
						maxMp += skillAdd[7];
						speed += skillAdd[8];
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

		// 内功（角色评分）
		this.score = FormulaScore.calcOnePet(this)[0];
	}

	public void fixHpMp() {
		hp = hp > maxHp ? maxHp : hp;
		mp = mp > maxMp ? maxMp : mp;
	}

	public Fighter getLikedFighter() {
		if (linkedFighter == null) {
			synchronized (this) {
				if (linkedFighter == null) {
					linkedFighter = new FighterPet(this);
				}
			}

		}
		return linkedFighter;
	}

	public Fighter getLikedFighter(int conff) {
		if (conff == 0) {
			return getLikedFighter();
		}
		return new FighterPet(this, conff);
	}

	/**
	 * 使用血包
	 */
	public synchronized void useBloodMagicBag() {
		if (level <= 10) {
			hp = maxHp;
			mp = maxMp;
			return;
		}
		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		int tmpBlood = NumberProcesser.between(maxHp - hp, 0, player.getBloodBag());
		int tmpMagic = NumberProcesser.between(maxMp - mp, 0, player.getMagicBag());
		if (tmpBlood > 0) {
			player.alterBloodBag(-tmpBlood);
			alterHp(tmpBlood);
		}
		if (tmpMagic > 0) {
			player.alterMagicBag(-tmpMagic);
			alterMp(tmpMagic);
		}
		hp = hp == 0 ? 1 : hp;
		mp = mp == 0 ? 1 : mp;
	}

	public void fullHpMp() {
		hp = maxHp;
		mp = maxMp;
	}

	public PetMode getMode() {
		return Context.getPetServer().getPetMode(modeId);
	}

	public long getExpNeed() {
		LevelUpgrade levelUpgrade = LevelUpgrade.getByLevel(level);
		return levelUpgrade.getPetExp();
	}

	/**
	 * 设置血量
	 * 
	 * @param alter
	 */
	public synchronized void alterHp(int alter) {
		int newHp = NumberProcesser.between(alter + getHp(), 0, getMaxHp());
		setHp(newHp);
	}

	/**
	 * 设置魔法量
	 * 
	 * @param alter
	 */
	public synchronized void alterMp(int alter) {
		int newMp = NumberProcesser.between(alter + getMp(), 0, getMaxMp());
		setMp(newMp);
	}

	public synchronized void alterExp(long alter) {
		exp += alter;
		autoUpLevel();// 检测是否升级
	}

	private synchronized void autoUpLevel() {
		boolean isUp = false;
		while (exp >= getExpNeed()) {
			setExp(exp - getExpNeed());
			level = level + 1;
			isUp = true;
		}
		if (isUp) {
			clacPropertys();
			hp = maxHp;
			mp = maxMp;
			try {
				ResponseMessage message = ResponseMessage.chatMsg(LanguageLib.get("pet.suc.upgrade", name, level));
				Context.getTcpServer().broadcastResMsg(message, playerId);
				commitSync();
				Player player = Context.getPlayerServer().getByPlayerId(playerId);
				Context.getPlayerServer().clacScore(player);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void alterSkillGird(int alter) {
		skillGird = NumberProcesser.between(skillGird + alter, 0, ConstantsModel.petSkillExpMax);
	}

	public PetVO toVO() {
		return new PetVO(this);
	}

	public BattlePetVO toTeamPetVO() {
		return new BattlePetVO(this);
	}

	@Override
	public boolean syncDB() {
		return Context.getSyncServer().syncDB(this);
	}

	public int getSpirit() {
		return spirit;
	}

	public void setSpirit(int spirit) {
		this.spirit = spirit;
	}

}
